﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.Assertions;

class CommandFunction: MonoBehaviour
{
    static public void UpdateMesh(string objName, object[] lsParam)
    {
        MeshData data = lsParam[0] as MeshData;
        TranFormData dataTranForm = null;
        if(lsParam.Length > 1)
        {
            dataTranForm = lsParam[1] as TranFormData;
        }
       
        if (data != null)
        {
            Loom.QueueOnMainThread(() =>
            {
                GameObject obj = FindObject(objName);
                if(obj == null)
                {
                    obj = new GameObject(objName);
                }

                if (obj.GetComponent<MeshFilter>() == null)
                {
                    obj.AddComponent<MeshFilter>();
                }

                if (obj.GetComponent<MeshRenderer>() == null)
                {
                 obj.AddComponent<MeshRenderer>();
                }

                if (dataTranForm != null)
                {
                    obj.transform.Rotate(dataTranForm.Angle[0], dataTranForm.Angle[1], dataTranForm.Angle[2]);
                    obj.transform.Translate(dataTranForm.Tranlate[0], dataTranForm.Tranlate[1], dataTranForm.Tranlate[2]);
                    obj.transform.localScale = new Vector3(dataTranForm.Scale[0], dataTranForm.Scale[1], dataTranForm.Scale[2]);

                }

                MeshFilter meshFilter = obj.GetComponent<MeshFilter>();
                Mesh mesh = meshFilter.mesh;
                mesh.Clear();

                mesh.vertices = data.MeshPoint;
                mesh.uv = data.uv;
                mesh.triangles = data.TriangleIndex;
                mesh.RecalculateNormals();

                if (obj.GetComponent<MeshCollider>() != null)
                {
                    DestroyImmediate(obj.GetComponent<MeshCollider>());
                }
                obj.AddComponent<MeshCollider>();

                UnityEngine.Object objct = Resources.Load("material/Default");
                Material mat = objct as Material;
                obj.GetComponent<MeshRenderer>().material = mat;

                if (obj == ObjSel.ObjSelBefore)
                {
                    DestroyImmediate(obj.GetComponent<WireFrameLineRenderer>());
                    obj.AddComponent<WireFrameLineRenderer>();
                }
            });

        }
    }


    static public void OffsetChange(String strObjName, object[] lsParam)
    {
        //  Debug.Assert(lsParam.Length == 1);
        Offset offset = lsParam[0] as Offset;
        Loom.QueueOnMainThread(() =>
        {
            GameObject obj = FindObject(strObjName);
            if (obj != null)
            {
                if(offset.MovType == Offset.MOVE_TYPE.TYPE_REL)
                {
                    if (Math.Abs(offset.Dis) > 0.01)
                    {
                        obj.transform.Translate(offset.Axis * offset.Dis);
                    }
                }
                else if (offset.MovType == Offset.MOVE_TYPE.TYPE_REL_PARENT )
                {
                    if(offset.ParentObjectName != null)
                    {
                        GameObject objParent = FindObject(offset.ParentObjectName);
                        if(objParent!=null)
                        {
                            Vector3 veDir = objParent.transform.TransformDirection(offset.Axis);//到世界坐标
                            veDir = obj.transform.InverseTransformDirection(veDir);
                            obj.transform.Translate(veDir * offset.Dis);
                        }
                    }
                }
                else if (offset.MovType == Offset.MOVE_TYPE.TYPE_ABS)
                {
                    Vector3 veDir = obj.transform.InverseTransformDirection(offset.Axis);
                    obj.transform.localPosition = veDir * offset.Dis;
                }
                else if (offset.MovType == Offset.MOVE_TYPE.TYPE_ABS_PARENT)
                {
                    GameObject objParent = FindObject(offset.ParentObjectName);
                    if (objParent != null)
                    {
                        Vector3 veDir = objParent.transform.TransformDirection(offset.Axis);
                        veDir = obj.transform.InverseTransformDirection(veDir);
                        obj.transform.localPosition = veDir * offset.Dis;
                    }
                }
            }
        }

        );
    }
    static public void RotateChange(String strObjName, object[] lsParam)
    {
       // Debug.Assert(lsParam.Length == 1);
        Rotate rotate = lsParam[0] as Rotate;
        Loom.QueueOnMainThread(() =>
        {
            GameObject obj = FindObject(strObjName);
            if (obj != null)
            {
                if (rotate.RotType == Rotate.ROTATE_TYPE.TYPE_REL)
                {
                    if (Math.Abs(rotate.Angle) > 0.01)
                    {
                        obj.transform.RotateAround(rotate.PntAxisOrign, rotate.Axis , rotate.Angle);
                    }
                }
                else if (rotate.RotType == Rotate.ROTATE_TYPE.TYPE_REL_PARENT)
                {
                    if (rotate.ParentObjectName != null)
                    {
                        GameObject objParent = FindObject(rotate.ParentObjectName);
                        if (objParent != null)
                        {
                            Vector3 veDir = objParent.transform.TransformDirection(rotate.Axis);//到世界坐标
                            veDir = obj.transform.InverseTransformDirection(veDir);

                            Vector3 pntOrign = objParent.transform.TransformDirection(rotate.PntAxisOrign);
                            pntOrign = obj.transform.InverseTransformDirection(pntOrign);

                            obj.transform.RotateAround(pntOrign, veDir, rotate.Angle);
                        }
                    }
                }
                else if (rotate.RotType == Rotate.ROTATE_TYPE.TYPE_ABS)
                {
                    Vector3 veDir = obj.transform.InverseTransformDirection(rotate.Axis);//到世界坐标
                  //  Vector3 pntOrign = obj.transform.TransformDirection(rotate.PntAxisOrign);
                    obj.transform.localRotation = new Quaternion();
                    obj.transform.RotateAround(rotate.PntAxisOrign, veDir, rotate.Angle);
                }
                else if (rotate.RotType == Rotate.ROTATE_TYPE.TYPE_ABS_PARENT)
                {
                    GameObject objParent = FindObject(rotate.ParentObjectName);
                    if (objParent != null)
                    {
                        Vector3 veDir = objParent.transform.TransformDirection(rotate.Axis);
                        veDir = obj.transform.InverseTransformDirection(veDir);

                        Vector3 pntOrign = objParent.transform.TransformDirection(rotate.PntAxisOrign);
                        obj.transform.localRotation = new Quaternion();
                        obj.transform.RotateAround(pntOrign, veDir, rotate.Angle);
                    }
                }
            }
        }

       );
    }
    static GameObject FindObject(String objName)
    {
        GameObject ret = null;
        if(m_vMemoryObj.ContainsKey(objName))
        {
            ret = m_vMemoryObj[objName];
        }
        else
        {
            ret = GameObject.Find(objName);
            if(ret != null)
            {
                m_vMemoryObj.Add(objName, ret);
            }
        }
        return ret;
    }


    static Dictionary<String, GameObject> m_vMemoryObj = new Dictionary<string, GameObject>();
}

class SendFunction
{
    static public byte[] SendObjectSel(String strObjSel)
    {
        byte[] ret, pData;
        String strFuncObjSel =  "SelectObjectChange" ;
        StreamSaveData fp = new StreamSaveData();
        fp.Write(strFuncObjSel);
        fp.Write(2);
        fp.Write("string");
        fp.Write(strObjSel);
        fp.Write("float");
        fp.Write(12.0f);
        pData = fp.GetData();
        ret = InitSendData(pData.Length);
        Array.Copy(pData, 0, ret, NetCommandDefine.GetHeadLength(), pData.Length);
        return ret;
    }
    static private byte[] InitSendData(int iDataLength)
    {
        byte[] ret = new byte[NetCommandDefine.GetHeadAndTailLength() + iDataLength];
        NetCommandDefine.SetHead(ref ret);
        NetCommandDefine.SetLength(ref ret, (uint)iDataLength);
        NetCommandDefine.SetTail(ref ret);
        NetCommandDefine.SetSendFunc(ref ret);
        NetCommandDefine.SetDeviceID(ref ret, 1000);
        NetCommandDefine.SetDeviceType(ref ret, 2);
        return ret;
    }

}


